package jvm.cmd.jstack;

/***
 *
 *
 * jstack  pid
 *
 * Found one Java-level deadlock:
 * =============================
 * "Thread-1":
 *   waiting to lock monitor 0x00007fdcd080eca8 (object 0x000000076ae8ea68, a java.lang.Object),
 *   which is held by "Thread-0"
 * "Thread-0":
 *   waiting to lock monitor 0x00007fdcd080ac08 (object 0x000000076ae8ea78, a java.lang.Object),
 *   which is held by "Thread-1"
 *
 * Java stack information for the threads listed above:
 * ===================================================
 * "Thread-1":
 *         at jvm.cmd.jstack.DeadLockTest$ThreadB.run(DeadLockTest.java:41)
 *         - waiting to lock <0x000000076ae8ea68> (a java.lang.Object)
 *         - locked <0x000000076ae8ea78> (a java.lang.Object)
 *         at java.lang.Thread.run(Thread.java:748)
 * "Thread-0":
 *         at jvm.cmd.jstack.DeadLockTest$ThreadA.run(DeadLockTest.java:22)
 *         - waiting to lock <0x000000076ae8ea78> (a java.lang.Object)
 *         - locked <0x000000076ae8ea68> (a java.lang.Object)
 *         at java.lang.Thread.run(Thread.java:748)
 *
 * Found 1 deadlock.
 *
 */
public class DeadLockTest {
        //定义资源
        private static Object obj1=new Object();
        private static Object obj2=new Object();
        //线程A：先获取到资源1，然后休眠2s，再获取资源2
        private static class ThreadA implements Runnable {
            @Override
            public void run() {
                synchronized (obj1) {
                    System.out.println("ThreadA获取到了OBJ1资源");

                    try {
                        //休眠2s，因为我们要将CPU资源让渡出去，这样线程B就可以先抢占obj2资源
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    synchronized (obj2) {
                        System.out.println("ThreadA获取到了OBJ2资源");
                    }
                }
            }
        }
        private static class ThreadB implements Runnable{
            @Override
            public void run() {
                synchronized (obj2){
                    System.out.println("ThreadB获取到了OBJ2资源");

                    try {
                        //休眠2s，因为我们要将CPU资源让渡出去，这样线程B就可以先抢占obj2资源
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    synchronized (obj1){
                        System.out.println("ThreadA获取到了OBJ1资源");
                    }
                }
            }
        }

        public static void main(String[] args) {
            new Thread(new ThreadA()).start();
            new Thread(new ThreadB()).start();
        }
}
